import prisma from '../api/prisma';
import { VideoType, Video } from '@prisma/client';
import { get } from '../utils/fetch';

// 采集视频类型API
const API_LIST_URL = 'https://api.yzzy-api.com/inc/apijson.php?ac=list';
// 采集视频详情API
const API_DETAIL_URL = 'https://api.yzzy-api.com/inc/apijson.php?ac=detail';

interface ApiVideoTypeResponse {
  code: number;
  msg: string;
  page: number;
  pagecount: number;
  limit: string;
  total: number;
  class: Array<{
    type_id: string;
    type_name: string;
  }>;
}

interface ApiVideoDetail {
  vod_id: string;
  vod_name: string;
  vod_enname: string;
  vod_sub: string;
  vod_letter: string;
  vod_color: string;
  vod_tag: string;
  vod_class: string;
  type_id: string;
  type_name: string;
  vod_pic: string;
  vod_lang: string;
  vod_area: string;
  vod_year: string;
  vod_remarks: string;
  vod_actor: string;
  vod_director: string;
  vod_serial: string;
  vod_lock: string;
  vod_level: string;
  vod_hits: string;
  vod_hits_day: string;
  vod_hits_week: string;
  vod_hits_month: string;
  vod_duration: string;
  vod_up: string;
  vod_down: string;
  vod_score: string;
  vod_score_all: string;
  vod_score_num: string;
  vod_points_play: string;
  vod_points_down: string;
  vod_content: string;
  vod_play_from: string;
  vod_play_note: string;
  vod_play_server: string;
  vod_play_url: string;
  vod_down_from: string;
  vod_down_note: string;
  vod_down_server: string;
  vod_down_url: string;
  vod_time: string;
}

interface ApiVideoDetailResponse {
  code: number;
  msg: string;
  page: number;
  pagecount: number;
  limit: string;
  total: number;
  list: ApiVideoDetail[];
}

// 视频类型转换函数
function convertToVideoType(apiType: { type_id: string; type_name: string }): Omit<VideoType, 'createdAt' | 'updatedAt'> {
  return {
    id: parseInt(apiType.type_id, 10),
    name: apiType.type_name,
    parentId: null,
    sort: 0,
    isVip: true,     // 默认为VIP分类
    isVisible: true, // 默认为可见分类
  };
}

// 视频详情转换函数
function convertToVideo(
  apiVideo: ApiVideoDetail, 
  videoTypeMap?: Map<number, VideoType>
): Omit<Video, 'createdAt' | 'updatedAt'| 'carouselPic'| 'isCarousel'> {
  const typeId = parseInt(apiVideo.type_id, 10);
  // 查找关联的视频类型
  const relatedType = videoTypeMap?.get(typeId);
  
  return {
    id: parseInt(apiVideo.vod_id, 10),
    vodName: apiVideo.vod_name,
    vodEnname: apiVideo.vod_enname || '',
    vodSub: apiVideo.vod_sub || '',
    vodLetter: apiVideo.vod_letter || '',
    vodColor: apiVideo.vod_color || '',
    vodTag: apiVideo.vod_tag || '',
    vodClass: apiVideo.vod_class || '',
    typeId: typeId,
    typeName: apiVideo.type_name || '',
    vodPic: apiVideo.vod_pic || '',
    vodLang: apiVideo.vod_lang || '',
    vodArea: apiVideo.vod_area || '',
    vodYear: apiVideo.vod_year || '',
    vodRemarks: apiVideo.vod_remarks || '',
    vodActor: apiVideo.vod_actor || '',
    vodDirector: apiVideo.vod_director || '',
    vodSerial: parseInt(apiVideo.vod_serial, 10) || 0,
    vodLock: parseInt(apiVideo.vod_lock, 10) || 0,
    vodLevel: parseInt(apiVideo.vod_level, 10) || 0,
    vodHits: parseInt(apiVideo.vod_hits, 10) || 0,
    vodHitsDay: parseInt(apiVideo.vod_hits_day, 10) || 0,
    vodHitsWeek: parseInt(apiVideo.vod_hits_week, 10) || 0,
    vodHitsMonth: parseInt(apiVideo.vod_hits_month, 10) || 0,
    vodDuration: parseInt(apiVideo.vod_duration, 10) || 0,
    vodUp: parseInt(apiVideo.vod_up, 10) || 0,
    vodDown: parseInt(apiVideo.vod_down, 10) || 0,
    vodScore: parseFloat(apiVideo.vod_score) || 0,
    vodScoreAll: parseInt(apiVideo.vod_score_all, 10) || 0,
    vodScoreNum: parseInt(apiVideo.vod_score_num, 10) || 0,
    vodPointsPlay: parseInt(apiVideo.vod_points_play, 10) || 0,
    vodPointsDown: parseInt(apiVideo.vod_points_down, 10) || 0,
    vodContent: (apiVideo.vod_content || '').trim(),
    vodPlayFrom: apiVideo.vod_play_from || '',
    vodPlayNote: apiVideo.vod_play_note || '',
    vodPlayServer: apiVideo.vod_play_server || 'no',
    vodPlayUrl: apiVideo.vod_play_url || '',
    vodDownFrom: apiVideo.vod_down_from || '0',
    vodDownNote: apiVideo.vod_down_note || '0',
    vodDownServer: apiVideo.vod_down_server || '0',
    vodDownUrl: apiVideo.vod_down_url || '0',
    vodTime: new Date(apiVideo.vod_time),
    // 使用关联的视频类型的设置，如果找不到则使用默认值
    isVip: relatedType?.isVip ?? true,
    isVisible: relatedType?.isVisible ?? true,
  };
}

// 采集视频类型
export async function crawlVideoTypes(): Promise<VideoType[]> {
  try {
    console.log('开始采集视频类型...');
    const { data } = await get<ApiVideoTypeResponse>(API_LIST_URL);
    
    if (data.code !== 1) {
      throw new Error(`API返回错误: ${data.msg}`);
    }
    
    const videoTypes = await Promise.all(
      data.class.map(async (apiType) => {
        const videoType = convertToVideoType(apiType);
        
        // 使用upsert确保不会重复插入
        return await prisma.videoType.upsert({
          where: { id: videoType.id },
          update: {
            name: videoType.name,
          },
          create: videoType,
        });
      })
    );
    
    console.log(`成功采集 ${videoTypes.length} 个视频类型`);
    return videoTypes;
  } catch (error) {
    console.error('采集视频类型失败:', error);
    throw error;
  }
}

// 采集视频详情 (可以传入页码和每页数量)
export async function crawlVideoDetails(
  page: number = 1, 
  limit: number = 20,
  hours?: number
): Promise<Video[]> {
  try {
    if (hours) {
      console.log(`开始采集视频详情... (页码: ${page}, 每页: ${limit}, 最近 ${hours} 小时)`);
    } else {
      console.log(`开始采集视频详情... (页码: ${page}, 每页: ${limit})`);
    }
    
    // 构建请求URL，如果指定了hours，添加h参数
    const url = `${API_DETAIL_URL}&pg=${page}&limit=${limit}`;
    // if (hours) {
    //   url += `&h=${hours}`;
    // }
    
    // 获取所有视频类型并创建ID到类型的映射，用于查找视频对应的类型属性
    const videoTypes = await prisma.videoType.findMany();
    const videoTypeMap = new Map<number, VideoType>();
    videoTypes.forEach(type => videoTypeMap.set(type.id, type));
    
    const { data } = await get<ApiVideoDetailResponse>(url);
    
    if (data.code !== 1) {
      throw new Error(`API返回错误: ${data.msg}`);
    }
    
    // 处理API返回的数据，传入视频类型映射
    const videoList = data.list.map(apiVideo => convertToVideo(apiVideo, videoTypeMap));
    
    // 如果指定了hours，过滤出最近hours小时内的视频
    let filteredVideoList = videoList;
    if (hours) {
      const hoursAgo = new Date();
      hoursAgo.setHours(hoursAgo.getHours() - hours);
      filteredVideoList = videoList.filter(video => video.vodTime >= hoursAgo);
      console.log(`过滤后剩余 ${filteredVideoList.length} 个视频（最近 ${hours} 小时内）`);
    }
    
    // 保存到数据库
    const videos = await Promise.all(
      filteredVideoList.map(async (video) => {
        
        return await prisma.video.upsert({
          where: { id: video.id },
          update: { ...video },
          create: video,
        });
      })
    );
    // 美化打印视频信息
    console.log('\n===== 采集到的视频信息 =====');
    console.log('ID\t视频名称');
    console.log('------------------------');
    videos.forEach(video => {
      console.log(`${video.id}\t${video.vodName}`);
    });
    console.log('========================\n');
    console.log(`成功采集 ${videos.length} 个视频详情`);
    return videos;
  } catch (error) {
    console.error('采集视频详情失败:', error);
    throw error;
  }
}

// 分页爬取所有视频详情
export async function crawlAllVideoDetails(
  startPage: number = 1,
  limit: number = 20,
  maxPages: number = Infinity,
  hours?: number
): Promise<{ totalCount: number; pages: number }> {
  try {
    if (hours) {
      console.log(`开始分页采集所有视频详情... (起始页: ${startPage}, 每页: ${limit}, 最大页数: ${maxPages}, 最近 ${hours} 小时)`);
    } else {
      console.log(`开始分页采集所有视频详情... (起始页: ${startPage}, 每页: ${limit}, 最大页数: ${maxPages})`);
    }
    
    let totalVideos = 0;
    let pagesProcessed = 0;
    const maxAllowedPages = startPage + maxPages;
    
    for (let currentPage = startPage; currentPage < maxAllowedPages; currentPage++) {
      // 直接调用crawlVideoDetails来获取当前页的视频
      const videos = await crawlVideoDetails(currentPage, limit, hours);
      
      // 如果没有获取到数据，说明已经到达了数据末尾
      if (videos.length === 0) {
        break;
      }
      
      totalVideos += videos.length;
      pagesProcessed++;
      console.log(`完成第 ${pagesProcessed} 页采集，本页 ${videos.length} 个视频`);
      
      // 如果获取的数据不足limit，说明已到达数据末尾
      if (videos.length < limit) {
        break;
      }
    }
    
    console.log(`分页采集完成，总共采集 ${totalVideos} 个视频，共 ${pagesProcessed} 页`);
    
    return {
      totalCount: totalVideos,
      pages: pagesProcessed,
    };
  } catch (error) {
    console.error('分页采集视频详情失败:', error);
    throw error;
  }
}

// 删除所有视频数据
export async function deleteAllVideos(): Promise<number> {
  try {
    console.log('开始删除所有视频数据...');
    const result = await prisma.video.deleteMany({});
    console.log(`成功删除 ${result.count} 个视频数据`);
    return result.count;
  } catch (error) {
    console.error('删除视频数据失败:', error);
    throw error;
  }
} 